/// Data types for events and spawned events
/** Provides structures for storing events in the event queue and records of
    spawned events in and event's spawned event list */
#ifndef EVENT_H
#define EVENT_H
//extern int assert(int);
#include "envelope.h"

/// List to store records of events spawned by a certain event
/** This information is used to cancel the spawn of an event should that
    event be rolled back */
class SpawnedEvent {
 public:
  /// Handle of the object the spawned event was sent to
  int objIdx;
  /// Timestamp of the spawned event
  POSE_TimeType timestamp;
  /// Event ID of the spawned event
  eventID evID;           
  /// Next spawned event in list
  SpawnedEvent *next;
  /// Basic Constructor
  SpawnedEvent() : objIdx(-1), timestamp(POSE_UnsetTS),next(NULL){ }
  /// Initializing constructor
  SpawnedEvent(int idx, eventID e, POSE_TimeType ts, SpawnedEvent *n) 
    :objIdx (idx), evID(e),  timestamp(ts), next(n)
    {
    }
  /// Pack/unpack/sizing operator
  void pup(PUP::er &p) { p(objIdx); p(timestamp); evID.pup(p); } 
};

/// Record to store all info about an event in eventQueue
class Event {
 public:
  /// The event's unique ID
  eventID evID;   
  /// The event method index associated with this event
  int fnIdx;      
  /// The timestamp of this event
  POSE_TimeType timestamp;    
  /// Execution status: 0=not done, 1=done, 2=executing
  int done;         
  /// Virtual start and end time
  POSE_TimeType svt, evt;
  /// Real start and end time
  double srt, ert;
  /// Flag indicating commit error
  int commitErr; 
  /// Buffered output generated by this event
  std::vector<char> commitBfr;
  /// The message corresponding to this event
  eventMsg *msg;  
  /// List of events spawned by this event
  SpawnedEvent *spawnedList;  
  /// Checkpointed state prior to execution of this event
  rep *cpData;    
  /// Serialized checkpointed state prior to execution of this event
  int serialCPdataSz;
  char *serialCPdata;    
  /// Links to next and previous events in event queue
  Event *next, *prev;
  /// Basic Constructor
  Event();        
  /// Destructor
  ~Event();
  /// Pack/unpack/sizing operator
  void pup(PUP::er &p);  
  /// Check validity of data fields
  void sanitize();
};

#endif
